import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt
import seaborn as sns
from typing import Dict, List, Tuple
import os
from pathlib import Path
"""
主要分析维度：
1. 教练个人能力维度
    1.1 专业技术指标：
        - 获奖率 = 获奖次数/执教次数
        - 金牌质量 = 金牌数/总奖牌数
        - 教练影响力 = 时间加权后的成绩提升率
    1.2 执教经验指标：
        - 执教年限
        - 跨国执教经验
        - 项目专精度
2.项目发展维度
    2.1 历史表现：
        - 近三届平均奖牌数
        - 金牌占比
        - 项目稳定性
        
    2.2 发展趋势：
        - 奖牌数增长率
        - 排名变化趋势
        - 竞争强度分析
3.投资价值维度
    3.1 基础评估：
        - 教练资源质量
        - 项目发展空间
        - 投资回报周期
        
    3.2 风险评估：
        - 教练年龄结构
        - 项目可持续性
        - 竞争环境变化

4. 预期效果维度
    4.1 短期效果：
        - 下届奥运会预期奖牌数
        - 排名提升空间
        - 投资收益率
        
    4.2 长期效果：
        - 人才培养体系建设
        - 技术积累与传承
        - 可持续发展能力
5. 综合评估维度
    5.1 量化指标：
    potential_score = (
        coach_impact * 0.4 +    # 教练影响力权重
        gold_ratio * 0.3 +      # 金牌质量权重
        medal_trend * 0.2 +     # 发展趋势权重
        experience_factor * 0.1  # 经验因素权重
    )
    
    5.2 定性指标：
        - 教练团队协作能力
        - 与运动员匹配度
        - 文化适应性
6. 国家特色维度
    6.1 优势项目：
        - 传统优势
        - 资源投入
        - 人才储备
        
    6.2 发展策略：
        - 重点突破项目
        - 潜力培育项目
        - 优势巩固项目
这些维度相互关联、相互影响，形成了一个完整的评估体系：
1.通过教练个人能力评估确定投资价值
2.结合项目发展趋势预测投资效果
3.考虑国家特色制定投资策略
4.基于综合评估做出最终决策

这样的多维度分析可以：
1.更全面地评估投资价值
2.更准确地预测投资效果
3.更有针对性地制定投资策略
4.更科学地进行决策支持
"""
class GreatCoachAnalyzer:
    def __init__(self):
        """初始化分析器"""
        self.coaches_data = None
        self.medals_data = None
        self.athletes_data = None
        self.coach_impact = {}
        
        # 添加时间衰减因子
        self.time_decay = 0.95  # 每过去4年,影响力衰减5%
        
        # 创建图片保存目录
        self.plot_dir = Path('coach_plots')
        self.plot_dir.mkdir(exist_ok=True)
        
        # 设置matplotlib中文显示
        plt.rcParams['font.sans-serif'] = ['Arial']  
        plt.rcParams['axes.unicode_minus'] = False
        
    def load_data(self):
        """加载数据"""
        try:
            # 使用gb18030编码读取包含中文的CSV文件
            self.coaches_data = pd.read_csv('coaches_info.csv', encoding='gb18030')
            self.medals_data = pd.read_csv('summerOly_medal_counts.csv')
            self.athletes_data = pd.read_csv('summerOly_athletes.csv')
            
            # 数据预处理
            self.coaches_data['Year'] = self.coaches_data['Year'].astype(int)
            self.medals_data['Year'] = self.medals_data['Year'].astype(int)
            
            # 清理教练名称数据
            self.coaches_data['final_coach'] = self.coaches_data['final_coach'].str.strip()
            
            # 将medals_data中的NOC列重命名为Country以保持一致性
            self.medals_data = self.medals_data.rename(columns={'NOC': 'Country'})
            
            # 添加奥运会周期列
            self.coaches_data['Olympic_Cycle'] = ((2024 - self.coaches_data['Year']) // 4)
            
            # 打印列名以检查
            print("Coaches data columns:", self.coaches_data.columns.tolist())
            print("Medals data columns:", self.medals_data.columns.tolist())
            
            return True
        except Exception as e:
            print(f"数据加载失败: {str(e)}")
            return False
            
    def get_average_performance(self, coach_data: pd.DataFrame, years: List[int]) -> float:
        """获取特定年份的平均表现"""
        year_data = coach_data[coach_data['Year'].isin(years)]
        medals = pd.merge(
            year_data,
            self.medals_data,
            on=['Country', 'Year']
        )
        
        if medals.empty:
            return 0
            
        return medals['Total'].mean()
        
    def calculate_coach_impact(self, coach_data: pd.DataFrame) -> float:
        """计算教练影响力"""
        impact = 0
        total_weight = 0
        
        # 获取教练执教的所有年份
        years = sorted(coach_data['Year'].unique())
        if len(years) <= 1:
            return 0  # 如果只有一年数据，影响力为0
            
        # 计算基准期的平均表现
        base_years = years[:2]  # 使用前两年作为基准期
        base_performance = self.get_average_performance(coach_data, base_years)
        
        # 计算后续年份的表现提升
        for year in years[2:]:
            cycle = (2024 - year) // 4
            weight = self.time_decay ** cycle
            
            year_performance = self.get_average_performance(coach_data, [year])
            improvement = (year_performance - base_performance) / base_performance if base_performance > 0 else 0
            
            impact += weight * improvement
            total_weight += weight
        
        return impact / total_weight if total_weight > 0 else 0

    def analyze_coach_success_rate(self) -> Dict:
        """分析教练的成功率"""
        coach_stats = {}
        
        for coach_name, coach_data in self.coaches_data.groupby('final_coach'):
            # 基础统计
            total_comps = len(coach_data)
            countries = set(coach_data['Country'])
            sports = set(coach_data['Sport'])
            years = set(coach_data['Year'])
            
            # 计算影响力
            impact_score = self.calculate_coach_impact(coach_data)
            
            # 获取奖牌数据
            medals_data = pd.merge(
                coach_data,
                self.medals_data,
                on=['Country', 'Year']
            )
            
            if not medals_data.empty:
                medal_comps = len(medals_data)
                gold_medals = medals_data['Gold'].sum()
                total_medals = medals_data['Total'].sum()
                
                # 计算成功率指标
                success_rate = medal_comps / total_comps
                gold_ratio = gold_medals / total_medals if total_medals > 0 else 0
                cross_country_rate = len(countries) / total_comps
                career_span = max(years) - min(years) if len(years) > 1 else 0
                
                coach_stats[coach_name] = {
                    'total_competitions': total_comps,
                    'medal_competitions': medal_comps,
                    'gold_medals': gold_medals,
                    'total_medals': total_medals,
                    'countries': countries,
                    'sports': sports,
                    'years': years,
                    'success_rate': success_rate,
                    'gold_ratio': gold_ratio,
                    'cross_country_rate': cross_country_rate,
                    'career_span': career_span,
                    'impact_score': impact_score
                }
        
        return coach_stats
    
    def get_sport_factor(self, sport: str) -> float:
        """计算项目发展潜力系数"""
        # 可以根据项目特性设置不同的权重
        sport_weights = {
            'Swimming': 1.2,  # 传统优势项目
            'Athletics': 1.2,
            'Gymnastics': 1.1,
            'Basketball': 1.0,
            'Volleyball': 1.0,
            'Boxing': 0.9,
            'Wrestling': 0.9
        }
        return sport_weights.get(sport, 1.0)
        
    def calculate_trend(self, medals_data: pd.DataFrame) -> float:
        """计算趋势"""
        if len(medals_data) < 2:
            return 0
            
        try:
            X = medals_data['Year'].values.reshape(-1, 1)
            y = medals_data['Total'].values
            model = LinearRegression()
            model.fit(X, y)
            return model.coef_[0]
        except:
            return 0
            
    def analyze_coaches(self, sport_data: pd.DataFrame) -> float:
        """分析教练因素"""
        coaches = sport_data['final_coach'].unique()
        coach_stats = self.analyze_coach_success_rate()
        coach_scores = []
        
        for coach in coaches:
            if coach in coach_stats:
                stats = coach_stats[coach]
                coach_score = (
                    stats['success_rate'] * 0.3 +
                    stats['gold_ratio'] * 0.3 +
                    stats['impact_score'] * 0.4
                )
                coach_scores.append(coach_score)
        
        return np.mean(coach_scores) if coach_scores else 0
    
    def recommend_sports_investment(self, country: str) -> List[Dict]:
        """为指定国家推荐重点投资的教练和运动项目"""
        country_data = self.coaches_data[self.coaches_data['Country'] == country]
        coach_analysis = {}
        
        # 按教练和项目分组分析
        for (coach, sport), group in country_data.groupby(['final_coach', 'Sport']):
            medals = pd.merge(
                group,
                self.medals_data,
                on=['Country', 'Year']
            )
            
            if not medals.empty:
                recent_medals = medals.sort_values('Year', ascending=False).head(3)
                career_span = max(group['Year']) - min(group['Year'])
                gold_ratio = medals['Gold'].sum() / medals['Total'].sum() if medals['Total'].sum() > 0 else 0
                
                coach_impact = self.calculate_coach_impact(group)
                
                # 只在有足够数据点时计算趋势
                if len(recent_medals) >= 2:
                    try:
                        medal_trend = np.polyfit(recent_medals['Year'], recent_medals['Total'], 1)[0]
                    except np.RankWarning:
                        medal_trend = 0  # 如果拟合不理想，使用0作为默认值
                else:
                    medal_trend = 0
                    
                potential_score = (
                    coach_impact * 0.4 +
                    gold_ratio * 0.3 +
                    medal_trend * 0.2 +
                    (career_span/20) * 0.1
                )
                
                coach_analysis[(coach, sport)] = {
                    'coach_name': coach,
                    'sport': sport,
                    'coach_impact': coach_impact,
                    'gold_ratio': gold_ratio,
                    'medal_trend': medal_trend,
                    'career_span': career_span,
                    'recent_performance': recent_medals['Total'].iloc[0],
                    'potential_score': potential_score,
                    'avg_medals': recent_medals['Total'].mean()
                }
        
        recommendations = [
            {
                'coach_sport': key,
                'analysis': value
            }
            for key, value in coach_analysis.items()
        ]
        
        return sorted(recommendations, 
                     key=lambda x: x['analysis']['potential_score'], 
                     reverse=True)
    
    def print_analysis_results(self, coach_stats: Dict, country_recommendations: Dict):
        """格式化打印分析结果"""
        print("\n========== Coach Impact Analysis ==========")
        print("\n1. Most Influential Coaches:")
        for i, (coach, stats) in enumerate(coach_stats.items(), 1):
            print(f"\n{i}. {coach}")
            print(f"   Specialization: {', '.join(stats['sports'])}")
            print(f"   Experience: {stats['career_span']} years")
            print(f"   Success Metrics:")
            print(f"   - Total Medals: {stats['total_medals']}")
            print(f"   - Gold Ratio: {stats['gold_ratio']:.1%}")
            print(f"   - Impact Score: {stats['impact_score']:.2f}")
        
        print("\n2. Investment Recommendations by Country:")
        for country, recommendations in country_recommendations.items():
            print(f"\n{country} Investment Priorities:")
            for i, rec in enumerate(recommendations[:3], 1):
                coach, sport = rec['coach_sport']
                analysis = rec['analysis']
                print(f"\n   {i}. Coach: {coach}")
                print(f"      Sport: {sport}")
                print(f"      Coach Impact: {analysis['coach_impact']:.2f}")
                print(f"      Gold Ratio: {analysis['gold_ratio']:.1%}")
                print(f"      Experience: {analysis['career_span']} years")
                print(f"      Recent Average Medals: {analysis['avg_medals']:.1f}")
                print(f"      Development Trend: {analysis['medal_trend']:.2f}")
                print(f"      Overall Potential Score: {analysis['potential_score']:.2f}")
                print(f"      Expected ROI: {analysis['potential_score'] * analysis['avg_medals']:.1f} medals")

    def plot_coach_impact_trend(self, coach_name: str, sport: str):
        """可视化教练的影响力趋势"""
        # 将中文名字转换为拼音或使用英文名字的一部分
        coach_name_clean = ''.join(char for char in coach_name if ord(char) < 128)
        if not coach_name_clean:
            coach_name_clean = f"Coach_{hash(coach_name) % 1000}"  # 使用哈希值作为标识
        
        coach_data = self.coaches_data[
            (self.coaches_data['final_coach'] == coach_name) &
            (self.coaches_data['Sport'] == sport)
        ]
        
        plt.figure(figsize=(12, 6))
        medals = pd.merge(
            coach_data,
            self.medals_data,
            on=['Country', 'Year']
        )
        
        if not medals.empty and len(medals) >= 2:  # 确保有足够的数据点
            plt.plot(medals['Year'], 
                    medals['Total'], 
                    marker='o',
                    label='Total Medals')
            plt.plot(medals['Year'], 
                    medals['Gold'], 
                    marker='s',
                    label='Gold Medals')
            
            plt.title(f'Impact Trend of {coach_name_clean} in {sport}', fontsize=14, pad=20)
            plt.xlabel('Year', fontsize=12)
            plt.ylabel('Number of Medals', fontsize=12)
            plt.legend()
            plt.grid(True, alpha=0.3)
            
            # 保存图片时使用清理后的名字
            plt.savefig(self.plot_dir / f'coach_{hash(coach_name) % 1000}_{sport}_impact.png', 
                        dpi=300, 
                        bbox_inches='tight',
                        pad_inches=0.2)
        plt.close()

    def plot_coach_analysis(self, coach_data, save_dir='coach_plots'):
        """生成教练分析的可视化图表"""
        # 设置字体
        plt.rcParams['font.sans-serif'] = ['Arial']
        plt.rcParams['axes.unicode_minus'] = False
        
        # 创建保存目录
        Path(save_dir).mkdir(parents=True, exist_ok=True)
        
        # 确保数据列名为英文
        coach_data = coach_data.rename(columns={
            'medal_count': 'Medal Count',
            'experience_years': 'Experience Years',
            'athlete_performance': 'Athlete Performance',
            'specialization': 'Specialization'
        })
        
        # 1. 教练获奖分布图
        plt.figure(figsize=(12, 6))
        medal_counts = coach_data['Medal Count'].value_counts().sort_index()
        plt.bar(medal_counts.index, medal_counts.values)
        plt.title('Distribution of Medals per Coach', fontsize=14, pad=20)
        plt.xlabel('Number of Medals', fontsize=12)
        plt.ylabel('Number of Coaches', fontsize=12)
        plt.grid(True, alpha=0.3)
        plt.savefig(f'{save_dir}/medal_distribution.png', dpi=300, bbox_inches='tight')
        plt.close()
        
        # 2. 教练经验分布图
        plt.figure(figsize=(12, 6))
        exp_counts = coach_data['Experience Years'].value_counts().sort_index()
        plt.bar(exp_counts.index, exp_counts.values)
        plt.title('Distribution of Coaching Experience', fontsize=14, pad=20)
        plt.xlabel('Years of Experience', fontsize=12)
        plt.ylabel('Number of Coaches', fontsize=12)
        plt.grid(True, alpha=0.3)
        plt.savefig(f'{save_dir}/experience_distribution.png', dpi=300, bbox_inches='tight')
        plt.close()
        
        # 3. 教练专业领域分布
        plt.figure(figsize=(12, 6))
        field_counts = coach_data['Specialization'].value_counts()
        # 确保专业领域名称也是英文
        field_counts.index = [field.title() for field in field_counts.index]
        
        plt.pie(field_counts, 
                labels=field_counts.index, 
                autopct='%1.1f%%',
                textprops={'fontsize': 10})
        plt.title('Distribution of Coaching Specializations', fontsize=14, pad=20)
        
        # 添加图例
        plt.legend(field_counts.index,
                  title='Specializations',
                  loc='center left',
                  bbox_to_anchor=(1, 0, 0.5, 1))
        plt.savefig(f'{save_dir}/specialization_distribution.png', dpi=300, bbox_inches='tight')
        plt.close()
        
        # 4. 经验与获奖关系散点图
        plt.figure(figsize=(12, 6))
        plt.scatter(coach_data['Experience Years'], 
                   coach_data['Medal Count'], 
                   alpha=0.5,
                   label='Coaches')
        plt.title('Relationship between Experience and Medals', fontsize=14, pad=20)
        plt.xlabel('Years of Experience', fontsize=12)
        plt.ylabel('Number of Medals', fontsize=12)
        plt.grid(True, alpha=0.3)
        
        # 添加趋势线
        z = np.polyfit(coach_data['Experience Years'], coach_data['Medal Count'], 1)
        p = np.poly1d(z)
        plt.plot(coach_data['Experience Years'], 
                p(coach_data['Experience Years']), 
                "r--", 
                alpha=0.8,
                label='Trend Line')
        plt.legend()
        
        plt.savefig(f'{save_dir}/experience_medal_correlation.png', dpi=300, bbox_inches='tight')
        plt.close()
        
        # 5. 教练影响力热力图
        plt.figure(figsize=(12, 8))
        impact_data = coach_data[['Medal Count', 'Experience Years', 'Athlete Performance']].corr()
        
        sns.heatmap(impact_data, 
                    annot=True, 
                    cmap='RdYlBu', 
                    center=0,
                    fmt='.2f',
                    annot_kws={'size': 10})
        plt.title('Coach Impact Correlation Matrix', fontsize=14, pad=20)
        
        # 调整标签位置以确保可见性
        plt.xticks(rotation=45, ha='right')
        plt.yticks(rotation=0)
        
        plt.tight_layout()
        plt.savefig(f'{save_dir}/coach_impact_heatmap.png', dpi=300, bbox_inches='tight')
        plt.close()

def main():
    analyzer = GreatCoachAnalyzer()
    
    if not analyzer.load_data():
        return
    
    # 1. 分析最成功的教练
    coach_stats = analyzer.analyze_coach_success_rate()
    top_coaches = sorted(
        coach_stats.items(),
        key=lambda x: x[1]['impact_score'],
        reverse=True
    )[:5]
    
    # 2. 为三个主要国家推荐投资项目
    target_countries = ['United States', 'China', 'Great Britain']
    country_recommendations = {}
    
    for country in target_countries:
        recommendations = analyzer.recommend_sports_investment(country)[:3]
        country_recommendations[country] = recommendations
    
    # 3. 打印分析结果
    analyzer.print_analysis_results(dict(top_coaches), country_recommendations)
    
    # 4. 为每个顶级教练生成影响力趋势图
    for coach, _ in top_coaches:
        for sport in analyzer.coaches_data[analyzer.coaches_data['final_coach'] == coach]['Sport'].unique():
            analyzer.plot_coach_impact_trend(coach, sport)

if __name__ == "__main__":
    main() 